import React,{useEffect,useState} from 'react';

const Child = (props: any, ref: any) => {
  /** useState*/
  useState(1);
  useState(2);
  useState(3);
  useState(4);

  useEffect(() => {
    console.log('a');
  });

  useEffect(() => {
    console.log('b');
  });

  useEffect(() => {
    console.log('c');
  });

  return <span>child</span>
};

export default class Chain extends React.Component {
  private _reactInternals: any;
  componentDidMount() {
    // debugger;
    console.log('this:',this)
    console.log('this._reactInternals:',this._reactInternals/** ← 这就是本组件节点对应的FiberNode对象*/);
    /*
      _reactInternals: FiberNode
        actualDuration: 2.399999976158142
        actualStartTime: 154.5
        alternate: null
        child: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
        childLanes: 0
        dependencies: null
        elementType: ƒ Chain()
        firstEffect: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
        flags: 5
        index: 0
        key: null
        lanes: 0
        lastEffect: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
        memoizedProps: {}
        memoizedState: null
        mode: 8
        nextEffect: null
        pendingProps: {}
        ref: null
        return: FiberNode {tag: 5, key: null, elementType: 'div', type: 'div', stateNode: div, …}
        selfBaseDuration: 0.5
        sibling: null
        stateNode: Chain {props: {…}, context: {…}, refs: {…}, updater: {…}, _reactInternals: FiberNode, …}
        tag: 1
        treeBaseDuration: 1.199999988079071
        type: ƒ Chain()
        updateQueue: {baseState: null, firstBaseUpdate: null, lastBaseUpdate: null, shared: {…}, effects: null}
        _debugHookTypes: null
        _debugID: 6
        _debugNeedsRemount: false
        _debugOwner: null
        _debugSource: null
        [[Prototype]]: Object
    */

    const childFiberNode = this._reactInternals/** ← 这就是FiberNode对象*/.child/** ← 这也是FiberNode,子FiberNode*/;
    console.log('childFiberNode:',childFiberNode);
    /*
    FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
      actualDuration: 1.300000011920929
      actualStartTime: 178.30000001192093
      alternate: null
      child: FiberNode {tag: 5, key: null, elementType: 'span', type: 'span', stateNode: span, …}
      childLanes: 0
      dependencies: null
      elementType: ƒ (props, ref)
      firstEffect: null
      flags: 517
      index: 0
      key: null
      lanes: 0
      lastEffect: null
      memoizedProps: {x: 1}
      memoizedState: {memoizedState: 1, baseState: 1, baseQueue: null, queue: {…}, next: {…}}
      mode: 8
      nextEffect: null
      pendingProps: {x: 1}
      ref: null
      return: FiberNode {tag: 1, key: null, stateNode: Chain, elementType: ƒ, type: ƒ, …}
      selfBaseDuration: 0.30000001192092896
      sibling: null
      stateNode: null
      tag: 0
      treeBaseDuration: 0.30000001192092896
      type: ƒ (props, ref)
      updateQueue: {lastEffect: {…}}
      _debugHookTypes: (6) ['useState', 'useState', 'useState', 'useEffect', 'useEffect', 'useEffect']
      _debugID: 8
      _debugNeedsRemount: false
      _debugOwner: FiberNode {tag: 1, key: null, stateNode: Chain, elementType: ƒ, type: ƒ, …}
      _debugSource: null
      [[Prototype]]: Object
    */

    console.log('childFiberNode.elementType:',childFiberNode.elementType);
    //就是我们的Child组件：
    /*
      childFiberNode.elementType: ƒ (props, ref) {
        react_1.useState(1);
        react_1.useState(2);
        react_1.useState(3);
        react_1.useEffect(function () {
          console.log('a');
        });
        react_1.…
    */

    console.log('childFiberNode.memoizedState:',childFiberNode.memoizedState);
    //↑ useState生成的一个链表(先调用useState的在前面) setState其实是让这里memoizedState发生变化
    /** 查看 memoizedState.png*/
    /*
      {memoizedState: 1, baseState: 1, baseQueue: null, queue: {…}, next: {…}}
        baseQueue: null
        baseState: 1
        memoizedState: 1
        next: {memoizedState: 2, baseState: 2, baseQueue: null, queue: {…}, next: {…}}
        queue: {pending: null, lastRenderedState: 1, dispatch: ƒ, lastRenderedReducer: ƒ}
        [[Prototype]]: Object
    */

    console.log('childFiberNode.memoizedProps:',childFiberNode.memoizedProps); // child接受的props
    /*
      {x: 1}
        x: 1
        [[Prototype]]: Object

    */

    console.log('childFiberNode.updateQueue:',childFiberNode.updateQueue);
    //↑ useEffect生成的一个链表
    /** */
    /*
      {lastEffect: {…}}
        lastEffect: {tag: 5, destroy: undefined, deps: null, next: {…}, create: ƒ}
        [[Prototype]]: Object
    */
    console.log(childFiberNode.updateQueue.lastEffect.create.toString());
    /*
      function () {
        console.log('c');
      }
    */
    console.log(childFiberNode.updateQueue.lastEffect.next.create.toString());
    /*
      function () {
        console.log('a');
      }
    */
    console.log(childFiberNode.updateQueue.lastEffect.next.next.create.toString());
    /*
      function () {
        console.log('b');
      }
    */
    console.log(childFiberNode.updateQueue.lastEffect.next.next.next.create.toString());
    /*
      function () {
        console.log('c');
      }
    */
    console.log(childFiberNode.updateQueue.lastEffect.next.next.next.next.create.toString());
    console.log(childFiberNode.updateQueue.lastEffect.next.next.next.next.next.create.toString());


    /** 在fiber系统了,更新分为两个阶段*/
    /*
      phase 1: render
        当你render时会产生一个virtual dom的树,这颗树的每一个节点都是一个fiber node
        每次render时会和前一个版本的virtual dom的树做比较
        做比较之后会产生一个更新序列

        setState发生在这个阶段 因为useState生成的是一个链表 故会有一个指针挨个操作

      phase 2: commit
        apply 每一个更新序列

        effects发生在这个阶段 因为useEffect生成的是一个链表 故会有一个指针挨个操作

      详情参见react/master/packages/react-reconciler/src
    */
  }

  render(){
    return <Child x={1}/>
  }
};
